<?php

include_once('SearchResults.php.inc');
include_once('QueryResult.php.inc');
class Models
{
    const BOOL="BooleanModel";
    const VSM_BOOL="VSM Bool";
    const VSM="VSM";
    const VSM_PAGERANK="VSM pagerank";
}
class Filters
{
    const TRIVIAL = 0;
    const TOP = 1;
    const THRESHOLD = 2;
}


class Evaluator{
	private $searchResults;
	private $queries;
	private $threshold;
	private $nbrTopResults = 10;
	
	public function Evaluator($queries, $threshold){
		$this->queries = $queries;
		$this->threshold=$threshold;
		$this->searchResults = array();
		$this->searchResults[Filters::TRIVIAL]=new SearchResults();
		$this->searchResults[Filters::TOP]=new SearchResults();
		$this->searchResults[Filters::THRESHOLD]=new SearchResults();
	}
	public function getSearchResults($filter){
		return $this->searchResults[$filter];
	}
	
	public function saveResults($model, $results){
		
		
		foreach($this->queries as $query => $relevants){
			//echo("Saving results for: ".$model.": QUERY:".$query."\r\n");
			$resultForQuery = $results[$query];
			arsort($resultForQuery);
			
			/*foreach($queryResult as $id=>$result){
				echo($id." ".$result."\r\n");
			}*/
			
			/*foreach($relevants as $docid){
				echo("Document id: ".$docid."\r\n");
			}*/
			
			$queryResult1=$this->evaluate($this->trivialRelevance($resultForQuery), $relevants);
			$this->searchResults[Filters::TRIVIAL]->addQueryResult($model, $query, $queryResult1);
			
			$queryResult2=$this->evaluate($this->trivialTopTenRelevance($resultForQuery), $relevants);
			$this->searchResults[Filters::TOP]->addQueryResult($model, $query, $queryResult2);
			
			/*echo("QUERY:".$query." :: MODEL:".$model." :: FILTER: Top\r\n");
			echo("F1:".$queryResult->f1Score."\r\n");
			echo("Recall:".$queryResult->recall."\r\n");
			echo("Precision:".$queryResult->precision."\r\n");*/
			
				
			$queryResult3=$this->evaluate($this->thresholdRelevance($resultForQuery), $relevants);
			$this->searchResults[Filters::THRESHOLD]->addQueryResult($model, $query, $queryResult3);
		}
	}
	
	public function setThreshold($newThreshold){
		$this->threshold=$newThreshold;
	}

	private function trivialRelevance($results){
		
		$filtered_results=array();
		foreach($results as $docId=>$sim){
			if($sim!=0){
				$filtered_results[]=$docId;
			}else{
				break;
			}
		}
		return $filtered_results;
	}

	private function trivialTopTenRelevance($results){
		//var_dump($results);
		$filtered_results=array();
		$counter=0;
		foreach($results as $docId=>$sim){
			if($sim != 0 && $counter < $this->nbrTopResults+1){
				$filtered_results[]=$docId;
			}else{
				break;
			}
			$counter++;
		}
		return $filtered_results;
	}
	
	private function thresholdRelevance($results){
		$filtered_results=array();
		foreach($results as $docId=>$sim){
			if($sim>=$this->threshold){
				$filtered_results[]=$docId;
			}else{
				break;
			}
		}
		return $filtered_results;
	}

	private function evaluate($filtered_results, $relevants){
		
		$relevantOfRetrieved=0;
		
		foreach($filtered_results as $docId2){
			if(in_array($docId2, $relevants)){
				$relevantOfRetrieved++;
			}
		}
		$recall=$relevantOfRetrieved/count($relevants);
		if(count($filtered_results) == 0){
			$precision = 0;
		}else{
			$precision = $relevantOfRetrieved/count($filtered_results);
		}
		if(($precision + $recall) == 0){
			$f1 = 0;
		}else{
			$f1 = (2 * $precision * $recall)/($precision + $recall);
		}
		$queryResult=new QueryResult();
		$queryResult->f1Score=$f1;
		$queryResult->precision=$precision;
		$queryResult->recall=$recall;
		$queryResult->ranks=$filtered_results;
		return $queryResult;
	}
}

?>
